/**
  ******************************************************************************
  * @file    app_pid.c
  * @author  Sherlock
  * @version V0.1
  * @date    08/12/2024
  * @brief   PID handling.
  ******************************************************************************
  * @copy
  *
  * <h2><center>&copy; COPYRIGHT 2010 Feirui</center></h2>
  */ 



/**
  * @brief  INCLUDE FILES.
  */
#ifndef	APP_GLOBALS_PID
#define	APP_GLOBALS_PID
#include <includes.h>
#include "pid_driver.h"
#include "pid_output.h"
#include "pid_timing.h"


static uint8_t PID_LocalRAMReset(void);

void App_Task_PID(void *p_arg)
{
	uint8_t  os_err, status = DEF_FALSE;
	OS_FLAGS os_value;
	
	(void)p_arg;

	/* RAM Reset */
  	status |= PID_LocalRAMReset();

	/* HW Interface Initial */
	status |= PID_HWInit();

	/* Wait for Start action finish */
	// OSSemPend(App_Sem_STARTSYNC,0,&os_err);   //等待某个任务先进行并释放信号量，其它任务才能开始运行

  	/* Wait for every task ready */
  	OSTimeDlyHMSM(0, 0, 0, 100);

  	/* HW start to work */
	status |= PID_HWEnable();

	/* Initial fault detection */
	if(status == DEF_FALSE)
		SYS_DebugERROR;

	/*  PID control flow */
 	while (DEF_TRUE)
	{
		/*  Wait for State Update output Flags  */
		os_value = OSFlagPend(App_Flags_PID,
							OSPIDFlags_ALL,
							OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
							0,
							&os_err);
		if(os_err!=OS_ERR_NONE)
		SYS_DebugERROR;                                       /* Error- Only for Debug */

		/*  Workload running */
		status = DEF_FALSE;
		if(os_value & OSPIDFlags_Timing)
		{
			status |= PID_TimingHandle();
		}
		if(os_value & OSPIDFlags_Output)
		{
			status |= PID_OutputHandle();
		}

	}
}


static uint8_t PID_LocalRAMReset(void)
{
	pidSynchronousCnt = 0;
	AVRStopDetectSta = DEF_FALSE;
	testBenchWorkMode = BenchWorkMode_Wait;
/*****************************************************************************
 *                                 计数器清零
 *****************************************************************************/
	AVRVoltCrankTiCnt = 0;
	AVRHWOffDelayTiCnt = 0;

/*****************************************************************************
 *                                 PID参数复位
 *****************************************************************************/
	PIDExcitationOutput.Kp = PIDBaseValueExcitationKP;
	PIDExcitationOutput.Ki = PIDBaseValueExcitationKI;
	PIDExcitationOutput.Kd = PIDBaseValueExcitationKD;
	PIDExcitationOutput.Kdf = 0.5;
	PIDExcitationOutput.LoopGain = 1;

	PIDStatorPIDOutput.Kp = PIDBaseValueStatorKP;
	PIDStatorPIDOutput.Ki = PIDBaseValueStatorKI;
	PIDStatorPIDOutput.Kd = PIDBaseValueStatorKD;
	PIDStatorPIDOutput.Kdf = 0.5;
	PIDStatorPIDOutput.LoopGain = 1;

	PIDStatorOutput.threshold = 0.001;
	InitPIDOutputObj();

	return DEF_TRUE;
}


/*****************************************************************************
 *                                 接口函数
 *****************************************************************************/
/* 合/分闸函数 */
PID_SyncActionResult PID_GeneratorSyncSwitch(PID_SyncAction status)
{
	switch (status)
	{
	case PIDSyncAction_Manual:
		if(testBenchWorkMode == BenchWorkMode_AVR)  //只能在AVR模式下合闸
		{
			testBenchWorkMode = BenchWorkMode_SyncManual;

			return PIDSyncActionResult_Action;
		}
		break;
	
	case PIDSyncAction_Auto:
		if(testBenchWorkMode == BenchWorkMode_AVR)  //只能在AVR模式下合闸
		{
			testBenchWorkMode = BenchWorkMode_SyncAuto;
			InitGovSyncErr();  //初始化合闸参数
			return PIDSyncActionResult_Action;
		}
		break;

	case PIDSyncAction_Open:
		if(testBenchWorkMode > BenchWorkMode_AVR)  //合闸过程中或已经合闸后，可以选择分闸
		{
			testBenchWorkMode = BenchWorkMode_Async;

			return PIDSyncActionResult_Action;
		}
		break;

	default:
		break;
	}
	
	return PIDSyncActionResult_Error;
}


/* 调整有功功率接口 */
uint8_t PID_AdjustPowerInterface(PID_AdjustAction action, float powerValue)
{
	if(testBenchWorkMode == BenchWorkMode_PF)
	{
		if(action == PIDAdjustAction_Adjust)
			PIDAdjustTarget[PIDAdjustTarget_ActivePower] += powerValue;
		else
			PIDAdjustTarget[PIDAdjustTarget_ActivePower] = powerValue;

		return DEF_TRUE;
	}
	return DEF_FALSE;
}


/* 调整功率因数接口 */
uint8_t PID_AdjustPFInterface(PID_AdjustAction action, float PFValue)
{
	if(testBenchWorkMode == BenchWorkMode_PF)
	{
		if(action == PIDAdjustAction_Adjust)
			PIDAdjustTarget[PIDAdjustTarget_PowerFactor] += PFValue;
		else
			PIDAdjustTarget[PIDAdjustTarget_PowerFactor] = PFValue;

		if(PIDAdjustTarget[PIDAdjustTarget_PowerFactor] > 1)
			PIDAdjustTarget[PIDAdjustTarget_PowerFactor] = 1;
		else if(PIDAdjustTarget[PIDAdjustTarget_PowerFactor] < -1)
			PIDAdjustTarget[PIDAdjustTarget_PowerFactor] = -1;
		
		return DEF_TRUE;
	}
	return DEF_FALSE;
}



#endif	/*	APP_GLOBALS_PID	*/

/******************* (C) COPYRIGHT 2010 Feirui *****END OF FILE****/